using Datacollection.Data.Models;
using Datacollection.Properties;
using Datacollection.Services.Logging;
using System;
using System.IO;
using System.Text;

namespace Datacollection.Services.Storage
{
    public class TestDataFileSaver
    {
        private string _rootSavePath;
        private string _dailyCsvPath;

        public TestDataFileSaver()
        {
            _rootSavePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestData");
            UpdateDailyCsvPath();
        }

        public void UpdateSavePath(string userSelectedPath)
        {
            if (!string.IsNullOrEmpty(userSelectedPath) && Directory.Exists(userSelectedPath))
            {
                _rootSavePath = userSelectedPath;
            }
            else
            {
                _rootSavePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestData");
            }
            UpdateDailyCsvPath();
        }

        private void UpdateDailyCsvPath()
        {
            string dateDir = DateTime.Now.ToString("yyyyMMdd");
            string dailyDir = Path.Combine(_rootSavePath, dateDir);

            if (!Directory.Exists(dailyDir))
            {
                Directory.CreateDirectory(dailyDir);
            }

            _dailyCsvPath = Path.Combine(dailyDir, $"{dateDir}_data.csv");
        }

        /// <summary>
        /// 保存测试数据，每个批次前添加三行独立信息：条码、测试时间、最终结果
        /// </summary>
        public string SaveTestData(TestSummary summary)
        {
            if (summary == null)
                throw new ArgumentNullException(nameof(summary));

            if (summary.TestItems == null || summary.TestItems.Count == 0)
                throw new Exception("测试批次中无测试项数据");

            try
            {
                bool isNewFile = !File.Exists(_dailyCsvPath);

                using (var stream = new FileStream(_dailyCsvPath, FileMode.Append, FileAccess.Write, FileShare.Read))
                using (var writer = new StreamWriter(stream, Encoding.UTF8))
                {

                    //表头
                    //WriteFileHeader(writer);


                    // 核心修改：每个测试批次前添加三行独立信息
                    writer.WriteLine("#每日测试数据汇总文件");
                    writer.WriteLine($"#创建日期: {DateTime.Now:yyyy-MM-dd}");
                    writer.WriteLine("#工单号: " + Settings.Default.mo_id);
                    writer.WriteLine("#部门编号: " + Settings.Default.deptID);
                    writer.WriteLine("#料号: " + Settings.Default.partID);
                    writer.WriteLine("#线别: " + Settings.Default.lineID);
                    writer.WriteLine("#机器编号: " + Settings.Default.machineSN);
                    writer.WriteLine("#测试通道: " + Settings.Default.testchannelID);
                    writer.WriteLine("#站位代码: " + Settings.Default.test_Station);

                    WriteBatchHeader(writer, summary);

                    // 测试项数据列头
                    
                    writer.WriteLine("--------------------------------------------------");
                    writer.WriteLine("测试项ID,测试类型,通道,测量值,单个状态,测试项时间");

                    // 写入当前批次的测试项数据
                    WriteTestItems(writer, summary);

                    // 批次结束后添加空行分隔，增强可读性
                    writer.WriteLine();
                }

                return _dailyCsvPath;
            }
            catch (Exception ex)
            {
                LogServiceLocator.Logger.Error("保存测试数据失败", ex);
                throw;
            }
        }

        /// <summary>
        /// 写入文件表头（仅新文件时执行）
        /// </summary>
        //private void WriteFileHeader(StreamWriter writer)
        //{
        //    // 文件级注释
        //    writer.WriteLine("#每日测试数据汇总文件");
        //    writer.WriteLine($"#创建日期: {DateTime.Now:yyyy-MM-dd}");
        //    writer.WriteLine("#工单号: " + Settings.Default.WorkOrder);
        //    writer.WriteLine("#治具编号: " + Settings.Default.FixtureNo);
 
            

        //}

        /// <summary>
        /// 写入批次头部信息（三行独立显示）
        /// </summary>
        private void WriteBatchHeader(StreamWriter writer, TestSummary summary)
        {
            // 1. 条码行（格式：#条码: XXXX）
            writer.WriteLine($"#条码: {EscapeCsvValue(Properties.Settings.Default.barcode)}");

            // 2. 测试时间行（格式：#测试时间: yyyy-MM-dd HH:mm:ss.fff）
            writer.WriteLine($"#测试时间: {summary.StartTime:yyyy-MM-dd HH:mm:ss.fff}");

            // 3. 最终结果行（格式：#最终结果: 通过/失败）
            string finalResult = !summary.IsFailed ? "通过" : "失败";
            writer.WriteLine($"#最终结果: {finalResult}");

            // 空行分隔批次头和测试项数据
            writer.WriteLine();
        }

        /// <summary>
        /// 写入当前批次的测试项数据
        /// </summary>
        private void WriteTestItems(StreamWriter writer, TestSummary summary)
        {
            foreach (var item in summary.TestItems)
            {
                // 测试项数据行（不含条码和最终结果，这些已在批次头单独列出）
                string line = $"{item.TestId}," +
                             $"{EscapeCsvValue(item.TestType)}," +
                             $"{EscapeCsvValue(GetChannelsText(item), true)}," +
                             $"{EscapeCsvValue(GetValueText(item))}," +
                             $"{GetStatusText(item)}," +
                             $"{item.TestTime:yyyy-MM-dd HH:mm:ss.fff}"; // 单个测试项时间

                writer.WriteLine(line);
            }
        }

        // 以下辅助方法保持不变
        private string GetChannelsText(TestResult item)
        {
            if (item is DcrTestResult dcr)
                return $"{dcr.Channel1}-{dcr.Channel2}";
            else if (item is IwTestResult iw)
                return $"{iw.Channel1}-{iw.Channel2}";
            else if (item is IrHipotTestResult ir)
                return $"{ir.Channel1},{ir.Channel2}";
            else return string.Empty;
        }

        private string GetValueText(TestResult item)
        {
            if (item is DcrTestResult dcr)
                return $"{dcr.Value}{dcr.Unit}";
            else if (item is IwTestResult iw)
                return $"{iw.Value1}, {iw.Value2}";
            else if (item is IrHipotTestResult ir)
                return $"{ir.Value}{ir.Unit}";
            else
                return string.Empty;
        }

        private string GetStatusText(TestResult item)
        {
            if (item is IwTestResult iw)
                return (iw.Status1 == "OK" && iw.Status2 == "OK") ? "OK" : "NG";
            else
                return item.Status;
        }

        private string EscapeCsvValue(string value, bool isChannel = false)
        {
            if (string.IsNullOrEmpty(value))
                return string.Empty;

            if (isChannel && value.Contains("-"))
                value = $"'{value}";

            if (value.Contains(",") || value.Contains("\""))
                return $"\"{value.Replace("\"", "\"\"")}\"";

            return value;
        }
    }
}
